package cn.wl.hrm.service.impl;

import cn.wl.hrm.config.ImageCodeProperties;
import cn.wl.hrm.domain.VerifyCode;
import cn.wl.hrm.dto.SendSmsDto;
import cn.wl.hrm.feign.client.RedisFeignClient;
import cn.wl.hrm.service.VerifyCodeService;
import cn.wl.hrm.util.AjaxResult;
import cn.wl.hrm.util.HttpUtil;
import cn.wl.hrm.util.StrUtils;
import cn.wl.hrm.util.VerifyCodeUtils;
import cn.wl.hrm.vo.SendSmsCodeVo;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Service
public class VerifyCodeServiceImpl implements VerifyCodeService {
    @Autowired
    private ImageCodeProperties imageCodeProperties;

    @Autowired
    private RedisFeignClient redisFeignClient;

    @Override
    public String createImageCode(String imageKey) {
        //判断参数是否为空
        if(org.apache.commons.lang.StringUtils.isBlank(imageKey)){
            throw new RuntimeException("无效的验证码key");
        }
        //获取随机的验证码
        String imageValue = StrUtils.getComplexRandomString(imageCodeProperties.getLength());
        System.out.println("验证码："+imageValue);
        //将图片验证码的值存到redis中，并设置过期时间
        AjaxResult imageCodeResult = redisFeignClient.setex(imageKey, imageCodeProperties.getTimeout(), imageValue);
        if(!imageCodeResult.isSuccess()){
            throw new RuntimeException("存储图片验证码到redis失败");
        }
        //使用工具类将验证码合并到一张图片中，并返回
        String imageCodeBase64Str = VerifyCodeUtils.VerifyCode(imageCodeProperties.getWidth(), imageCodeProperties.getHeight(), imageValue);
        //返回经过base64编码的图片
        return imageCodeBase64Str;
    }

    @Override
    public void sendSmsCode(SendSmsDto sendSmsDto) {
        //获取前端传来的参数
        String mobile = sendSmsDto.getMobile();
        String imageCode = sendSmsDto.getImageCode();
        String imageCodeKey = sendSmsDto.getImageCodeKey();
        //对参数进行判断
        if(!StringUtils.hasLength(mobile)){
            throw new RuntimeException("无效的手机号码");
        }
        if(!StringUtils.hasLength(imageCode)){
            throw new RuntimeException("无效的图片验证码");
        }
        if(!StringUtils.hasLength(imageCodeKey)){
            throw new RuntimeException("无效的图片验证码key");
        }
        //从redis中获取图片验证码
        AjaxResult ajaxResult = redisFeignClient.get(imageCodeKey);
        //判断验证码是否为空
        if(!ajaxResult.isSuccess() || ajaxResult.getResultObj() == null){
            throw new RuntimeException("获取redis数据失败");
        }
        //将redis中验证码转换为string类型
        String imageCodeFromRedis = ajaxResult.getResultObj().toString();
        //判断用户输入的验证码是否正确
        if(!imageCodeFromRedis.toUpperCase().equals(imageCode.toUpperCase())){
            throw new RuntimeException("验证码错误，请重新输入!");
        }
        //设置短信验证码的key
        String smsCodeKey = VerifyCode.SMS_CODE_KEY+mobile;
        //获取当前时间
        Date now = new Date();
        //短信验证码的值
        String smsCodeVlaue = null;
        //如果redis已有验证码，并且验证码还未过期，就将该验证码再发送给用户
        AjaxResult sendSmsCodeVoResult = redisFeignClient.get(smsCodeKey);
        //判断redis中是否已经存在验证码
        if(sendSmsCodeVoResult.isSuccess() && sendSmsCodeVoResult.getResultObj() != null){
            //获取到redis中的信息，转换为string类型
            String sendSmsCodeVoJson = sendSmsCodeVoResult.getResultObj().toString();
            //转换为sendSmsCodeVo对象
            SendSmsCodeVo sendSmsCodeVo = JSON.parseObject(sendSmsCodeVoJson, SendSmsCodeVo.class);
            //判断用户发送验证码的间隔是否小于60s
            if((now.getTime()-sendSmsCodeVo.getSendTime().getTime())/1000 < 60){
                throw new RuntimeException("发送频繁，请稍后再试！");
            }
            //将sendSmsCodeVo对象中验证码的值直接赋值给smsCodeVlaue
            smsCodeVlaue = sendSmsCodeVo.getSmsCodeValue();
        }else {
            //如果redis没有验证码，则生成验证码
            smsCodeVlaue = StrUtils.getRandomString(VerifyCode.SMS_CODE_LENGTH);
        }
        //将短信验证信息封装成对象
        SendSmsCodeVo sendSmsCodeVo = new SendSmsCodeVo(smsCodeVlaue, now);
        //转换为json字符串
        String sendSmsCodeVoJson = JSON.toJSONString(sendSmsCodeVo);
        //将验证码存到redis
        AjaxResult result = redisFeignClient.setex(smsCodeKey, imageCodeProperties.getTimeout(), sendSmsCodeVoJson);
        if(!result.isSuccess()){
            throw new RuntimeException("短信验证码缓存到redis失败");
        }
        //发送短信验证码给用户，调用短信接口
        String message = "您的验证码为：" + smsCodeVlaue + ",请您在5分钟内使用！";

        Map<String, String> params = new HashMap<>();
        params.put("Uid", "wl243763066");
        params.put("Key", "d41d8cd98f00b204e980");
        params.put("smsMob",mobile);
        params.put("smsText", message);
        HttpUtil.sendPost("http://utf8.api.smschinese.cn/",params);
        System.out.println(message);


    }


}
